<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>语音聊天测试</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            background: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        .test-section {
            margin-bottom: 30px;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 8px;
        }
        
        .test-section h3 {
            margin-top: 0;
            color: #333;
        }
        
        input, textarea, button {
            margin: 10px 5px;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        
        button {
            background: #007bff;
            color: white;
            cursor: pointer;
            border: none;
        }
        
        button:hover {
            background: #0056b3;
        }
        
        button:disabled {
            background: #ccc;
            cursor: not-allowed;
        }
        
        .result {
            margin-top: 10px;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 5px;
            white-space: pre-wrap;
        }
        
        .error {
            background: #f8d7da;
            color: #721c24;
        }
        
        .success {
            background: #d4edda;
            color: #155724;
        }
        
        .audio-player {
            margin-top: 10px;
        }
        
        audio {
            width: 100%;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎤 AI语音助手测试页面</h1>
        
        <!-- 健康检查 -->
        <div class="test-section">
            <h3>1. 健康检查</h3>
            <button onclick="testHealth()">检查后端服务状态</button>
            <div id="healthResult" class="result"></div>
        </div>
        
        <!-- 文本聊天测试 -->
        <div class="test-section">
            <h3>2. 文本聊天测试</h3>
            <input type="text" id="textInput" placeholder="输入测试文本" style="width: 300px;" />
            <button onclick="testTextChat()">发送文本消息</button>
            <div id="textChatResult" class="result"></div>
            <div id="textAudioPlayer" class="audio-player"></div>
        </div>
        
        <!-- WebSocket连接测试 -->
        <div class="test-section">
            <h3>3. WebSocket连接测试</h3>
            <button id="wsConnectBtn" onclick="testWebSocket()">连接WebSocket</button>
            <button onclick="testWebSocketMessage()" disabled id="wsSendBtn">发送WebSocket消息</button>
            <div id="wsResult" class="result"></div>
        </div>
        
        <!-- 录音功能测试 -->
        <div class="test-section">
            <h3>4. 录音功能测试</h3>
            <button id="recordBtn" onclick="toggleRecording()">开始录音</button>
            <span id="recordingTime"></span>
            <div id="recordResult" class="result"></div>
            <audio id="recordedAudio" controls style="display: none;"></audio>
        </div>
    </div>

    <script>
        const API_BASE = 'http://localhost:8123/api';
        const WS_URL = 'ws://localhost:8123/ws/voice-chat';
        
        let ws = null;
        let mediaRecorder = null;
        let audioChunks = [];
        let isRecording = false;
        let recordingStartTime = 0;
        let recordingTimer = null;

        // 健康检查
        async function testHealth() {
            const resultDiv = document.getElementById('healthResult');
            resultDiv.textContent = '检查中...';
            
            try {
                const response = await fetch(`${API_BASE}/chat/health`);
                const result = await response.text();
                resultDiv.textContent = `✅ 后端服务正常: ${result}`;
                resultDiv.className = 'result success';
            } catch (error) {
                resultDiv.textContent = `❌ 后端服务连接失败: ${error.message}`;
                resultDiv.className = 'result error';
            }
        }

        // 文本聊天测试
        async function testTextChat() {
            const textInput = document.getElementById('textInput');
            const resultDiv = document.getElementById('textChatResult');
            const audioPlayerDiv = document.getElementById('textAudioPlayer');
            
            if (!textInput.value.trim()) {
                alert('请输入测试文本');
                return;
            }
            
            resultDiv.textContent = '处理中...';
            resultDiv.className = 'result';
            audioPlayerDiv.innerHTML = '';
            
            try {
                const response = await fetch(`${API_BASE}/chat/voice`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        textInput: textInput.value,
                        sessionId: 'test-session-' + Date.now()
                    })
                });
                
                const result = await response.json();
                
                if (result.status === 'success') {
                    resultDiv.innerHTML = `✅ 处理成功 (耗时: ${result.processingTime}ms)
识别文本: ${result.recognizedText}
AI回复: ${result.aiResponse}`;
                    resultDiv.className = 'result success';
                    
                    // 播放返回的音频
                    if (result.audioBase64) {
                        const audioBlob = base64ToBlob(result.audioBase64, 'audio/webm');
                        const audioUrl = URL.createObjectURL(audioBlob);
                        const audio = document.createElement('audio');
                        audio.controls = true;
                        audio.src = audioUrl;
                        audioPlayerDiv.appendChild(audio);
                        
                        // 自动播放
                        setTimeout(() => audio.play().catch(e => console.log('自动播放失败:', e)), 500);
                    }
                } else {
                    resultDiv.textContent = `❌ 处理失败: ${result.errorMessage}`;
                    resultDiv.className = 'result error';
                }
            } catch (error) {
                resultDiv.textContent = `❌ 请求失败: ${error.message}`;
                resultDiv.className = 'result error';
            }
        }

        // WebSocket测试
        function testWebSocket() {
            const resultDiv = document.getElementById('wsResult');
            const connectBtn = document.getElementById('wsConnectBtn');
            const sendBtn = document.getElementById('wsSendBtn');
            
            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.close();
                return;
            }
            
            resultDiv.textContent = '连接中...';
            connectBtn.disabled = true;
            
            try {
                ws = new WebSocket(WS_URL);
                
                ws.onopen = () => {
                    resultDiv.textContent = '✅ WebSocket连接成功';
                    resultDiv.className = 'result success';
                    connectBtn.textContent = '断开连接';
                    connectBtn.disabled = false;
                    sendBtn.disabled = false;
                };
                
                ws.onmessage = (event) => {
                    const data = JSON.parse(event.data);
                    resultDiv.textContent += `
收到消息: ${JSON.stringify(data, null, 2)}`;
                };
                
                ws.onclose = () => {
                    resultDiv.textContent += '
WebSocket连接已关闭';
                    connectBtn.textContent = '连接WebSocket';
                    connectBtn.disabled = false;
                    sendBtn.disabled = true;
                };
                
                ws.onerror = (error) => {
                    resultDiv.textContent = `❌ WebSocket连接错误: ${error}`;
                    resultDiv.className = 'result error';
                    connectBtn.disabled = false;
                };
            } catch (error) {
                resultDiv.textContent = `❌ WebSocket创建失败: ${error.message}`;
                resultDiv.className = 'result error';
                connectBtn.disabled = false;
            }
        }

        // 发送WebSocket消息
        function testWebSocketMessage() {
            if (!ws || ws.readyState !== WebSocket.OPEN) {
                alert('WebSocket未连接');
                return;
            }
            
            const message = {
                textInput: '这是一条WebSocket测试消息',
                sessionId: 'ws-test-session-' + Date.now()
            };
            
            ws.send(JSON.stringify(message));
        }

        // 录音功能
        async function toggleRecording() {
            if (isRecording) {
                stopRecording();
            } else {
                await startRecording();
            }
        }

        async function startRecording() {
            const resultDiv = document.getElementById('recordResult');
            const recordBtn = document.getElementById('recordBtn');
            
            try {
                const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
                
                mediaRecorder = new MediaRecorder(stream);
                audioChunks = [];
                
                mediaRecorder.ondataavailable = (event) => {
                    audioChunks.push(event.data);
                };
                
                mediaRecorder.onstop = () => {
                    const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
                    const audioUrl = URL.createObjectURL(audioBlob);
                    
                    const audio = document.getElementById('recordedAudio');
                    audio.src = audioUrl;
                    audio.style.display = 'block';
                    
                    // 转换为Base64并发送到后端测试
                    const reader = new FileReader();
                    reader.onload = () => {
                        const base64Data = reader.result.split(',')[1]; // 移除data:audio/webm;base64,前缀
                        testVoiceRecognition(base64Data);
                    };
                    reader.readAsDataURL(audioBlob);
                    
                    resultDiv.textContent = `✅ 录音完成，时长: ${Math.floor((Date.now() - recordingStartTime) / 1000)}秒`;
                    resultDiv.className = 'result success';
                    
                    // 停止所有音轨
                    stream.getTracks().forEach(track => track.stop());
                };
                
                mediaRecorder.start();
                isRecording = true;
                recordingStartTime = Date.now();
                
                recordBtn.textContent = '停止录音';
                resultDiv.textContent = '🎤 正在录音...';
                resultDiv.className = 'result';
                
                // 开始计时
                recordingTimer = setInterval(updateRecordingTime, 1000);
                
            } catch (error) {
                resultDiv.textContent = `❌ 录音启动失败: ${error.message}`;
                resultDiv.className = 'result error';
            }
        }

        function stopRecording() {
            if (mediaRecorder && isRecording) {
                mediaRecorder.stop();
                isRecording = false;
                
                const recordBtn = document.getElementById('recordBtn');
                recordBtn.textContent = '开始录音';
                
                clearInterval(recordingTimer);
                document.getElementById('recordingTime').textContent = '';
            }
        }

        function updateRecordingTime() {
            if (isRecording) {
                const elapsed = Math.floor((Date.now() - recordingStartTime) / 1000);
                const minutes = Math.floor(elapsed / 60);
                const seconds = elapsed % 60;
                document.getElementById('recordingTime').textContent = 
                    `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
            }
        }

        // 测试语音识别
        async function testVoiceRecognition(base64Audio) {
            const resultDiv = document.getElementById('recordResult');
            
            try {
                resultDiv.textContent += '\n🎯 正在测试语音识别...';
                
                const response = await fetch(`${API_BASE}/chat/voice`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        audioBase64: base64Audio,
                        sessionId: 'voice-test-session-' + Date.now()
                    })
                });
                
                const result = await response.json();
                
                if (result.status === 'success') {
                    resultDiv.textContent += `\n✅ 语音识别成功！
识别文本: ${result.recognizedText}
AI回复: ${result.aiResponse}
处理时间: ${result.processingTime}ms`;
                    
                    // 播放返回的音频
                    if (result.audioBase64) {
                        const audioBlob = base64ToBlob(result.audioBase64, 'audio/webm');
                        const audioUrl = URL.createObjectURL(audioBlob);
                        const audio = new Audio(audioUrl);
                        audio.play().catch(e => console.log('音频播放失败:', e));
                    }
                } else {
                    resultDiv.textContent += `\n❌ 语音识别失败: ${result.errorMessage}`;
                }
            } catch (error) {
                resultDiv.textContent += `\n❌ 语音识别请求失败: ${error.message}`;
            }
        }

        // 工具函数：Base64转Blob
        function base64ToBlob(base64, mimeType) {
            const byteCharacters = atob(base64);
            const byteNumbers = new Array(byteCharacters.length);
            for (let i = 0; i < byteCharacters.length; i++) {
                byteNumbers[i] = byteCharacters.charCodeAt(i);
            }
            const byteArray = new Uint8Array(byteNumbers);
            return new Blob([byteArray], { type: mimeType });
        }

        // 页面加载时自动检查健康状态
        window.addEventListener('load', () => {
            testHealth();
        });
    </script>
</body>
</html>
